Package com.aptana.interactive_console.console

Source Code of com.aptana.interactive_console.console.ScriptXmlRpcClient

/**
* Copyright (c) 2005-2011 by Appcelerator, Inc. All Rights Reserved.
* Licensed under the terms of the Eclipse Public License (EPL).
* Please see the license.txt included with this distribution for details.
* Any modifications to this file must keep this entire header intact.
*/
package com.aptana.interactive_console.console;

import java.net.MalformedURLException;
import java.net.URL;

import org.apache.xmlrpc.XmlRpcException;
import org.apache.xmlrpc.XmlRpcRequest;
import org.apache.xmlrpc.client.AsyncCallback;
import org.apache.xmlrpc.client.XmlRpcClient;
import org.apache.xmlrpc.client.XmlRpcClientConfigImpl;

import com.aptana.shared_core.io.ThreadStreamReader;
import com.aptana.shared_core.net.LocalHost;
import com.aptana.shared_core.string.StringUtils;

/**
* Subclass of XmlRpcClient that will monitor the process so that if the process is destroyed, we stop waiting
* for messages from it.
*
* @author Fabio
*/
public class ScriptXmlRpcClient implements IXmlRpcClient {

    /**
     * Internal xml-rpc client (responsible for the actual communication with the server)
     */
    private XmlRpcClient impl;

    /**
     * The process where the server is being executed.
     */
    private Process process;

    /**
     * This is the thread that's reading the error stream from the process.
     */
    private ThreadStreamReader stdErrReader;

    /**
     * This is the thread that's reading the output stream from the process.
     */
    private ThreadStreamReader stdOutReader;

    /**
     * Constructor (see fields description)
     */
    public ScriptXmlRpcClient(Process process, ThreadStreamReader stdErrReader, ThreadStreamReader stdOutReader) {
        this.impl = new XmlRpcClient();
        this.process = process;
        this.stdErrReader = stdErrReader;
        this.stdOutReader = stdOutReader;
    }

    /**
     * Sets the port where the server is started.
     * @throws MalformedURLException
     */
    public void setPort(int port) throws MalformedURLException {
        XmlRpcClientConfigImpl config = new XmlRpcClientConfigImpl();
        config.setServerURL(new URL("http://" + LocalHost.getLocalHost() + ":" + port));

        this.impl.setConfig(config);
    }

    /**
     * Executes a command in the server.
     *
     * Within this method, we should be careful about being able to return if the server dies.
     * If we wanted to have a timeout, this would be the place to add it.
     *
     * @return the result from executing the given command in the server.
     */
    public Object execute(String command, Object[] args) throws XmlRpcException {
        final Object[] result = new Object[] { null };

        //make an async call so that we can keep track of not actually having an answer.
        this.impl.executeAsync(command, args, new AsyncCallback() {

            public void handleError(XmlRpcRequest request, Throwable error) {
                result[0] = new Object[] { error.getMessage() };
            }

            public void handleResult(XmlRpcRequest request, Object receivedResult) {
                result[0] = receivedResult;
            }
        });

        //busy loop waiting for the answer (or having the console die).
        while (result[0] == null) {
            try {
                if (process != null) {
                    final String errStream = stdErrReader.getContents();
                    if (errStream.indexOf("sys.exit called. Interactive console finishing.") != -1) {
                        result[0] = new Object[] { errStream };
                        break;
                    }

                    int exitValue = process.exitValue();
                    result[0] = new Object[] { StringUtils.format(
                            "Console already exited with value: %s while waiting for an answer.\n" + "Error stream: "
                                    + errStream + "\n" + "Output stream: " + stdOutReader.getContents(), exitValue) };

                    //ok, we have an exit value!
                    break;
                }
            } catch (IllegalThreadStateException e) {
                //that's ok... let's sleep a bit
                synchronized (this) {
                    try {
                        wait(10);
                    } catch (InterruptedException e1) {
                        //                        Log.log(e1);
                    }
                }
            }
        }
        return result[0];
    }

}
TOP

Related Classes of com.aptana.interactive_console.console.ScriptXmlRpcClient

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.